#include <xme802_4.h>
// #include "libmaple/dac.h"
#include "pt100_hx711.h"

#include <ELClient.h>
#include <ELClientCmd.h>
#include <ELClientWebServer.h>
#include <time.h>
#include <ArduinoJson.h>

ELClient esp(&Serial1, &Serial1);
ELClientWebServer webServer(&esp);
// Initialize CMD client (for GetTime)
ELClientCmd elcmd(&esp);
uint8_t xx1, xx2, xx3, xx4, xp1;
uint8_t yy1, yy2, yy3, yy4, yy5, yy6;
uint16_t ya1, ya2;
int xa1, xt1, xr1;
// DEFINE_USART_RS485(serial2, 2, PF9, PF9);
// DEFINE_USART_RS485(serial3, 3, PF8, PF8);
// DEFINE_UART_485(serial4, 4, -1, -1);
char fwname[] = "xme802_ori";
volatile int build = BUILD_NUMBER;
pt100_hx711 pt100(PE14, PE15);
uint32_t uptime;
bool connected;
// Callback made from esp-link to notify of wifi status changes
// Here we just print something out for grins
void wifiCb(void *response)
{
    ELClientResponse *res = (ELClientResponse *)response;
    if (res->argc() == 1)
    {
        uint8_t status;
        res->popArg(&status, 1);

        if (status == STATION_GOT_IP)
        {
            Serial1.println("WIFI CONNECTED");
            connected = true;
        }
        else
        {
            Serial1.print("WIFI NOT READY: ");
            Serial1.println(status);
        }
    }
}
void resetCb(void)
{
    Serial.println("EL-Client (re-)starting!");
    bool ok = false;
    do
    {
        ok = esp.Sync(); // sync up with esp-link, blocks for up to 2 seconds
        if (!ok)
            Serial.println("EL-Client sync failed!");
    } while (!ok);
    Serial.println("EL-Client synced!");

    webServer.setup();
}
void ioCb(char *url)
{
    char str[512];
    StaticJsonDocument<512> doc;
    sprintf(str, "%d", xa1);
    doc["XA1"] = str;
    doc["XP1"] = xp1 ? "1" : "0";
    sprintf(str, "%d", xt1);
    doc["XT1"] = str;
    doc["X1"] = xx1 ? "1" : "0";
    doc["X2"] = xx2 ? "1" : "0";
    doc["X3"] = xx3 ? "1" : "0";
    doc["X4"] = xx4 ? "1" : "0";
    doc["Y1"] = yy1 ? "1" : "0";
    doc["Y2"] = yy2 ? "1" : "0";
    doc["Y3"] = yy3 ? "1" : "0";
    doc["Y4"] = yy4 ? "1" : "0";
    doc["Y5"] = yy5 ? "1" : "0";
    doc["Y6"] = yy6 ? "1" : "0";

    serializeJson(doc, str);
    webServer.setArgString(F("text"), str);
}
void setup()
{
    Serial1.begin(115200);
    Serial1.print(fwname);
    Serial1.print(build);
    pcf8563.begin();
    pinMode(X1, INPUT_PULLUP);
    pinMode(X2, INPUT_PULLUP);
    pinMode(X3, INPUT_PULLUP);
    pinMode(X4, INPUT_PULLUP);
    pinMode(XP1, INPUT_PULLUP);
    pinMode(Y1, OUTPUT);
    pinMode(Y2, OUTPUT);
    pinMode(Y3, OUTPUT);
    pinMode(Y4, OUTPUT);
    pinMode(Y5, OUTPUT);
    pinMode(Y6, OUTPUT);
    pinMode(PE13, OUTPUT);
    pinMode(XA1, INPUT_ANALOG);
    pinMode(YA1, OUTPUT);
    pinMode(YA2, OUTPUT);
    pt100.begin();

    URLHandler *ioHandler = webServer.createURLHandler(F("/dat.html.json"));
    ioHandler->loadCb.attach(&ioCb);
    ioHandler->refreshCb.attach(&ioCb);
    //   ioHandler->buttonCb.attach(&ledButtonPressCb);

    esp.wifiCb.attach(wifiCb); // wifi status change callback, optional (delete if not desired)

    esp.resetCb = resetCb;
    resetCb();
}
static uint32_t last;
void loop()
{
    uptime = millis() / 60000;
    esp.Process();

    if (connected && (millis() - last) > 4000)
    {
        Serial1.println("publishing");

        uint32_t t = elcmd.GetTime();
        Serial1.print("Time: ");
        Serial1.println(t);
        if (t > 99999999)
        {
            struct tm *ct = gmtime((time_t *)&t);
            pcf8563.setDateTime(ct->tm_yday, ct->tm_wday, ct->tm_mon, 0, ct->tm_year, ct->tm_hour, ct->tm_min, ct->tm_sec);
        }
        last = millis();
    }
    digitalWrite(PE13, 0);
    xx1 = digitalRead(X1) ? 0 : 1;
    xx2 = digitalRead(X2) ? 0 : 1;
    xx3 = digitalRead(X3) ? 0 : 1;
    xx4 = digitalRead(X4) ? 0 : 1;
    xa1 = analogRead(XA1);
    xp1 = digitalRead(XP1) ? 0 : 1;
    pt100.loop();
    xt1 = pt100.value();
    xr1 = pt100.rvalue();
    digitalWrite(Y1, yy1 ? 0 : 1);
    digitalWrite(Y2, yy2 ? 0 : 1);
    digitalWrite(Y3, yy3 ? 0 : 1);
    digitalWrite(Y4, yy4 ? 0 : 1);
    digitalWrite(Y5, yy5 ? 0 : 1);
    digitalWrite(Y6, yy6 ? 0 : 1);
    analogWrite(YA1, ya1);
    analogWrite(YA2, ya2);
    // Serial1.print(xx1);
    // Serial1.println("loop"); //
}